﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Geometry;
using System.Diagnostics;

namespace TestGeometry {
    public class TestVector {
        public static float EPSILON = 1e-3f;

        public void run() {
            testAddition();
            testSubtruction();
            testMultiply();
            testDiv();
            testDot();
            testCross();
            testSquare();
            testLength();
        }

        public void testAddition() {
            Vector u = new Vector(1e0f, 1e3f, 1e5f);
            Vector v = new Vector(1e1f, 1e4f, 1e6f);

            Vector res = u + v;
            Util.assertEquals(res.x, u.x + v.x);
            Util.assertEquals(res.y, u.y + v.y);
            Util.assertEquals(res.z, u.z + v.z);
        }

        public void testSubtruction() {
            Vector u = new Vector(1e1f, 1e2f, 1e3f);
            Vector v = new Vector(1e0f, 1e1f, 1e2f);

            Vector res = u - v;
            Util.assertEquals(res.x, u.x - v.x);
            Util.assertEquals(res.y, u.y - v.y);
            Util.assertEquals(res.z, u.z - v.z);
        }

        public void testMultiply() {
            Vector v = new Vector(1.0f, 1.0f, 1.0f);
            float a = 10.0f;

            Vector res = v * a;
            Vector comp = new Vector(a * v.x, a * v.y, a * v.z);
            Util.assertZero(Math.Abs((res - comp).length()));
        }

        public void testDiv() {
            Vector v = new Vector(10.0f, 10.0f, 10.0f);
            Vector u = new Vector(1.0f, 1.0f, 1.0f);
            float a = 10.0f;

            Vector res = v / a;
            Util.assertZero((res - u).square());
        }

        public void testDot() {
            Vector u = new Vector(1.0f, 0.0f, 0.0f);
            Vector v = new Vector(0.0f, 1.0f, 0.0f);
            Vector w = new Vector(0.0f, 0.0f, 1.0f);

            Util.assertEquals(u.dot(u), 1.0f);
            Util.assertEquals(v.dot(v), 1.0f);
            Util.assertEquals(w.dot(w), 1.0f);
            Util.assertEquals(u.dot(v), 0.0f);
            Util.assertEquals(v.dot(w), 0.0f);
            Util.assertEquals(w.dot(u), 0.0f);
        }

        public void testCross() {
            Vector u = new Vector(1.0f, 0.0f, 0.0f);
            Vector v = new Vector(0.0f, 1.0f, 0.0f);
            Vector w = new Vector(0.0f, 0.0f, 1.0f);

            Vector uv = u.cross(v);
            Util.assertEquals(uv.x, w.x);
            Util.assertEquals(uv.y, w.y);
            Util.assertEquals(uv.z, w.z);
        }

        public void testSquare() {
            float d = 2.0f;
            float d2 = d * d;
            Vector v = new Vector(d, d, d);
            Vector w = new Vector(-d, -d, -d);

            Util.assertEquals(v.square(), 3 * d2);
            Util.assertEquals(v.square(), w.square());
        }

        public void testLength() {
            float d = 2.0f;
            Vector v = new Vector(d, d, d);
            Vector w = new Vector(-d, -d, -d);

            Util.assertEquals(v.length(), w.length());
            Util.assertEquals(v.length(), (float)Math.Sqrt(3 * (d * d)));
        }
    }

}
